home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / C de cerca / Ejemplos / Capítulo 3 / CdeCerca.c < prev   
C/C++ Source or Header  |  1996-01-24  |  21KB  |  601 lines

  1. /*****************************************************************/
  2. /*
  3.       C de Cerca 3
  4.       Toolbox de Apple
  5.       ResEdit
  6.       Eventos
  7.       Menú Archivo (Salir de la aplicación)
  8.             
  9.         Rafael Escoté - Enric Herrera
  10.         BlauSoft S.L. para MacFormat España - 1996
  11.                     
  12.         La descripción del código y la información sobre cómo preparar
  13.         el entorno de programación y generar estos programas, está contenida
  14.         en el ejemplar de MacFormat que los acompaña.
  15.  
  16. */
  17. /*****************************************************************/
  18.  
  19.  
  20.  
  21. /*
  22. LA TOOLBOX Y LOS FICHEROS 'UNIVERSAL HEADERS'
  23. ==============================================
  24. La Toolbox es una colección de funciones escritas por Apple
  25. que han sido ya compiladas y colocadas en los chips de ROM de cada
  26. Mac. 
  27. Para poder emplear en nuestros programas una de dichas funciones,
  28. debemos informar al compilador acerca de los posibles parámetros
  29. y valores de salida requeridos.
  30. En otras palabras, el compilador necesita el prototipo de la función
  31. existente en la Toolbox de forma que pueda verificar que el uso que de
  32. ella hagamos en nuestro programa sea correcto.
  33. Los ficheros APPLE UNIVERSAL HEADERS proporcionados por Apple no
  34. son más que ficheros de texto conteniendo los prototipos de cada una de
  35. las funciones de la Toolbox.
  36.  
  37. NOTA: Sólo para los más curiosos: En la carpeta que contiene el compilador,
  38. veréis una carpeta llamada 'MacOS Support' y en su interior una carpeta
  39. llamada 'Headers' y dentro de ella una carpeta llamada
  40. 'Universal Headers', que contiene todos los ficheros creados por Apple.
  41. */
  42.  
  43.  
  44.  
  45. /* 
  46. COMO DIFERENCIAR FUNCIONES PROPIAS Y DE LA TOOLBOX
  47. ===================================================
  48. A las funciones creadas por nosotros para este programa (y que por lo
  49. tanto no pertenecen a la Toolbox) les hemos dado nombres que comienzan
  50. por las iniciales MF. Por ejemplo, MF_PlaySnd(), MF_RandomColor() etc...
  51. Todas las restantes funciones que aparecen empleadas en el código, SON
  52. FUNCIONES PERTENECIENTES A LA TOOLBOX DE APPLE.
  53. (Una excepción: La función main() la hemos creado nosotros pero su nombre
  54. no puede ser otro que main(), por convención)
  55.  
  56.  
  57.  
  58. /****************************************************************    */
  59. /* PROTOTIPOS    DE LAS FUNCIONES QUE HEMOS CREADO                                         */
  60. /* PARA NUESTRO PROGRAMA                                                                                    */ 
  61. /****************************************************************    */
  62. void        main(void);                /* Esta función NO puede tener otro nombre */
  63. void        MF_InitToolbox         (void);
  64. void         MF_SetupMenus            (void);
  65. void         MF_AbreMiVentana    (void);
  66. void         MF_EscribeTexto        (void);
  67. void         MF_bucle_principal(void);
  68. void         MF_MenuBar                (long algoSeleccionado);
  69. void         MF_Update                    (WindowPtr ventana_a_refrescar);
  70.  
  71.  
  72.  
  73. /****************************************************************    */
  74. /* CONSTANTES Y VARIABLES GLOBALES                                                                 */
  75. /* DE USO GENERAL                                                                                                    */ 
  76. /****************************************************************    */
  77. Boolean gAcabarProg = false; /* Una variable global. 
  78.                                                                 Como siempre, las variables globales
  79.                                                                 las prefijamos con la letra 'g'.
  80.                                                                 Cuando gAcabarProg sea = true,
  81.                                                                 acabaremos el programa */
  82.  
  83.  
  84.  
  85. /****************************************************************    */
  86. /* CONSTANTES Y VARIABLES GLOBALES                                                                 */
  87. /* RELACIONADAS CON LOS MENUS EN NUESTRO PROGRAMA                                    */ 
  88. /****************************************************************    */
  89. /* 
  90. Hemos editado el fichero CdeCerca_3.µ.rsrc creando en él un recurso nuevo
  91. de tipo MENU con el nº de identificación 129.
  92. Declaramos una constante con dicho valor para simplificar el código
  93. */
  94. #define            kArchivoMenuID    129    /* Nuevo recurso 'MENU' para nuestro menú Archivo */
  95. #define            kSalirItem            1        /* Nº de la opción 'Salir' en el menú Archivo */
  96.  
  97. /* 
  98. Crearemos un menú empleando las funciones de la Toolbox,
  99. GetMenu() e InsertMenu(). GetMenu() nos devuelve un handle (especie de puntero)
  100. al menú recién creado. Hemos de declarar pues, una variable adecuada...
  101. */ 
  102. MenuHandle    gArchivoMenu;                /* Nuestro menú archivo, una vez creado */
  103.  
  104.  
  105.  
  106. /****************************************************************    */
  107. /* CONSTANTES Y VARIABLES GLOBALES                                                                 */
  108. /* RELACIONADAS CON LA VENTANA QUE ABRIREMOS                                            */ 
  109. /****************************************************************    */
  110. /* La ventana que abriremos será creada dinámicamente por medio de
  111. la función NewWindow() que nos devolverá un puntero a la estructura de
  112. la nueva ventana, Declaramos pues, una variable adecuada... */
  113.     
  114. WindowPtr        gMiVentana = nil;/* Variable de tipo 'pointer'.
  115.                                                                 Puntero a una estructura
  116.                                                                 de tipo WindowRecord  definida por Apple
  117.                                                                 en el fichero UNIVERSAL HEADER Windows.h
  118.                                                                 y que corresponderá 
  119.                                                                 a la ventana que crearemos 
  120.                                                                 NOTA sólo para curiosos: De hecho,
  121.                                                                 una variable WindowPtr apunta a la 
  122.                                                                 estructura GrafPort que forma parte de
  123.                                                                 la estructura WindowRecord. */
  124.  
  125.                                                                 
  126.                                                                 
  127. /*--------------------------------------------------------------------*/
  128. /* 
  129.     A PARTIR DE ESTE PUNTO, APARECE EL CODIGO DE LAS FUNCIONES CREADAS
  130.     ESPECIFICAMENTE PARA ESTE PROGRAMA. 
  131.     
  132. */
  133. /*--------------------------------------------------------------------*/
  134.  
  135.  
  136.  
  137. /****************************************************************    */
  138. /* main()                                                                 */
  139. /****************************************************************    */
  140. /*
  141.     Todos los programas en C poseen una función que debe llamarse main.
  142.     (NO PERTENECE A LA TOOLBOX)
  143.     Cuando un programa se pone en marcha, lo hace SIEMPRE ejecutando
  144.     en primer lugar la función main().
  145.     Es el punto de entrada a nuestra aplicación.
  146.     
  147.     Recibe:     nada
  148.     Que hace: Llama otras funciones que preparan la aplicación...
  149.     Salida:      void (nada)
  150. */
  151. void    main (void)
  152. {    
  153.     /* Antes de hacer nada, debemos inicializar la Toolbox del Mac                 */
  154.     /* Como sea que el procedimiento a seguir para inicializar la Toolbox */
  155.     /* es casi siempre el mismo, hemos creado una función MF_InitToolbox()*/
  156.     /* que contiene las llamadas estándar de inicialización */
  157.  
  158.     MF_InitToolbox();
  159.  
  160.     /* Ahora debemos preparar y mostrar la barra de menú, que contendrá */
  161.     /* los menús propios de nuestra aplicación */
  162.     
  163.     MF_SetupMenus();
  164.     
  165.     /* Ahora empleamos una función se encargará de abrir una ventana */
  166.     MF_AbreMiVentana();
  167.     
  168.     /* Una vez abierta la ventana, podemos escribir algo de texto en ella */
  169.     MF_EscribeTexto();
  170.     
  171.     /* Y ya podemos entrar en el bucle principal, que se encargará de
  172.          recoger e interpretar las acciones del usuario */    
  173.     MF_bucle_principal();
  174.     
  175.     /* Cuando el bucle principal haya terminado, será porque el usuario
  176.          desea acabar el programa.
  177.          Debemos liberar la memoria ocupada por nuestra ventana. */
  178.     DisposeWindow(gMiVentana);
  179.     
  180.   /* Y ya está, al acabarse la función main(), el Sistema cerrará
  181.          nuestra aplicación de forma automática */
  182.     
  183. } /* Fin de main() y del programa */
  184.  
  185.  
  186.  
  187. /****************************************************************    */
  188. /* MF_bucle_principal                                                     */
  189. /****************************************************************    */
  190. /*
  191.     Recibe:     nada
  192.     Que hace: Entra en un bucle y espera que se produzca una acción (evento)
  193.                         Según cual sea este, reacciona llamando una de las funciones que
  194.                         hemos creado en esta demo.
  195.     Salida:      nada
  196. */
  197. void MF_bucle_principal(void)
  198. {
  199.     /* Declaramos una variable del tipo EventRecord que llamaremos el_Evento */
  200.     EventRecord    el_Evento;     
  201.                                 /* 
  202.                                 Un EventRecord es una estructura declarada
  203.                                 por Apple en el fichero UNIVERSAL HEADER
  204.                                 Events.h y formada por las siguientes
  205.                                 variables:
  206.                                                          
  207.                             struct EventRecord {
  208.                                     EventKind                what;         (qué evento)
  209.                                     UInt32                    message;    (datos del evento)
  210.                                     UInt32                    when;            (cuando se produce)
  211.                                     Point                        where;        (coordenadas del evento)
  212.                                     EventModifiers    modifiers;(estado de las teclas
  213.                                                                                             especiales: CMD, Opt, etc...) 
  214.                                     };
  215.                                 */
  216.     
  217.     WindowPtr    la_ventana;    /* Guardaremos un puntero que nos indicará en que
  218.                                                      ventana (si es el caso) se ha producido un evento */
  219.     
  220.     
  221.     short    zona_de_la_ventana; /* También guardaremos el código que indica
  222.                                                              la zona de la ventana en que se produce un evento
  223.                                                              si es del tipo mouseDown
  224.                                                         */
  225.                                                         
  226.     
  227.     Boolean    hay_evento;    /* valor de salida de la función WaitNextEvent */
  228.                                             /* Lo ignoraremos en esta demo */
  229.     
  230.     while (gAcabarProg == false)
  231.     /* Mientras la variable global gAcabarProg sea falsa, repetiremos este bucle */
  232.     /* Cuando el usuario seleccione 'Salir' del menú Archivo, cambiaremos el */
  233.     /* valor de gAcabarProg a true (cierto) */
  234.     {
  235.         
  236.         hay_evento = WaitNextEvent(everyEvent, &el_Evento, 0L, 0L);
  237.         /* WaitNextEvent es una función de la ToolBox que nos proporciona
  238.              información acerca de las posibles acciones del usuario o eventos del
  239.              Sistema. Para ello, 'llena' de información las variables de la estructura
  240.              EventRecord (el_Evento, en nuestro caso) */ 
  241.         
  242.         switch(el_Evento.what) /* what nos indica qué evento hemos recibido */
  243.         {
  244.             case nullEvent:
  245.                     /* Ignoramos eventos nulos (ningún evento).*/
  246.             break;
  247.                     
  248.             case keyDown:
  249.             /* Se ha pulsado una tecla. Comprobaremos si también se ha pulsado
  250.                  la tecla de CMD y si es así, llamaremos la función que responde
  251.                  a la selección de opciones de menú */
  252.                 if(el_Evento.modifiers & cmdKey) /* Tecla de CMD pulsada? */
  253.                 {
  254.                MF_MenuBar(MenuKey( el_Evento.message & charCodeMask) ) ;
  255.            }
  256.             break;
  257.                     
  258.             case autoKey:
  259.                 /* Ignoramos los eventos de repetición, generados al mantener
  260.                      pulsada una tecla */
  261.             break;
  262.                     
  263.             case mouseDown:
  264.             /* clic del ratón en algún sitio...*/
  265.                 zona_de_la_ventana = FindWindow(el_Evento.where,&la_ventana);
  266.                 switch (zona_de_la_ventana)
  267.                 {
  268.                     case inDrag:/* clic en la barra de título. Para que el usuario     */
  269.                                             /* pueda arrastrar la ventana, simplemente hemos de    */
  270.                                             /* usar la función DragWindow() que se encarga del    */
  271.                                             /* proceso, hasta que se suelte el botón del ratón     */
  272.                         DragWindow(la_ventana,el_Evento.where,&qd.screenBits.bounds);
  273.                     break;
  274.                             
  275.                     case inMenuBar: /* clic en la barra de menús */
  276.                         MF_MenuBar(MenuSelect(el_Evento.where));
  277.                     break;
  278.                             
  279.                     default:
  280.                         /* Ignoramos clics en otras zonas de la ventana */
  281.                     break;
  282.                 }
  283.             break;
  284.                     
  285.             case mouseUp:
  286.             /* ignoraremos los eventos producidos al soltar el botón del ratón */
  287.             break;
  288.                 
  289.             case diskEvt:
  290.             /* También ignoraremos los eventos producidos al insertar un disco */
  291.             break;
  292.                 
  293.             case updateEvt:
  294.                 /*     Una ventana debe ser refrescada. Llamamos la función
  295.                         MF_Update, pasándole un puntero a la ventana en cuestión.
  296.                         La variable message de la estructura EventRecord, contiene
  297.                         dicho puntero, pero es necesario forzar (cast) su tipo al
  298.                         de WindowPtr
  299.                 */
  300.                 la_ventana = (WindowPtr)el_Evento.message;
  301.                 MF_Update( la_ventana );
  302.             break;
  303.                 
  304.             default:
  305.             /* En cualquier otro caso, ignoramos el evento */
  306.             break;
  307.                 
  308.         } /* Fin de switch(el_Evento.what) */
  309.             
  310.     } /* Fin de while (gAcabarProg == false) */
  311.         
  312.         
  313. } /* Fin de la función MF_bucle_principal() */
  314.  
  315.  
  316.  
  317. /****************************************************************    */
  318. /* MF_Update                                                                       */
  319. /****************************************************************    */
  320. /*
  321.     Esta función se emplea cuando MF_bucle_principal ha detectado un evento
  322.     del tipo updateEvt. El sistema lo genera cuando una ventana activa
  323.     es desplazada o cuando una ventana que no era la activa es activada.
  324.     En estos casos, la zona de la ventana que permanecía
  325.     oculta por otras ventanas debe ser refrescada, re-dibujando su contenido.
  326.     El sistema controla todas las ventanas abiertas y genera un evento updateEvt
  327.     cuando alguna zona de una ventana necesita ser refrescada.
  328.     
  329.     Recibe:     un puntero a la ventana que debe ser refrescada.
  330.     Que hace: Esta demo aprovecha la función MF_EscribeTexto(). Cuando la ventana
  331.                         necesita refrescarse, simplemente llamamos de nuevo MF_EscribeTexto()
  332.                         y la ventana se actualizará.
  333.                         
  334.     Salida:      void (nada)
  335. */
  336. void MF_Update( WindowPtr ventana_a_refrescar)
  337. {
  338.  
  339.     GrafPtr  old_port;                            /* Declaración de una variable de tipo
  340.                                                                          puntero (pointer) a un área gráfica */
  341.     
  342.     GetPort( &old_port );                        /* Preservamos el área gráfica actual */
  343.     
  344.     SetPort( ventana_a_refrescar );    /* Cambiamos de área, seleccionando la
  345.                                                                         correspondiente a la ventana que debe
  346.                                                                         refrescarse */
  347.   
  348.   BeginUpdate( ventana_a_refrescar );
  349.    
  350.     /* Aqui deberíamos llamar las funciones adecuadas para re-dibujar los
  351.          contenidos de nuestra ventana.  En este caso re-escribimos un texto
  352.          en la ventana
  353.     */
  354.          
  355.      MF_EscribeTexto();
  356.              
  357.     EndUpdate( ventana_a_refrescar );
  358.  
  359.     SetPort( old_port );                    /* recuperamos el área gráfica inicial */
  360.     
  361. } /* Fin de MF_Update() */
  362.  
  363.  
  364.  
  365. /****************************************************************    */
  366. /* MF_MenuBar                                                                       */
  367. /****************************************************************    */
  368. /*
  369.     Esta función reacciona cuando MF_bucle_principal ha detectado que el clic
  370.     del ratón se ha producido en la barra de menús de nuestro programa.
  371.     
  372.     Recibe:     una variable con la información del menu e item seleccionados
  373.     Que hace: Actúa en función de la posible selección de un item de alguno
  374.                         de nuestros menús.
  375.     Salida:      void (nada)
  376. */
  377. void MF_MenuBar(long algoSeleccionado)
  378. {
  379.     short    Que_Menu;
  380.     short    Que_Opcion;
  381.     short dummy;
  382.     Str255 ItemName;
  383.     GrafPtr oldPort;
  384.     
  385.     if(algoSeleccionado != 0L)
  386.     {
  387.         /* algoSeleccionado es un valor de tipo long (4 bytes)
  388.              que contiene en los 2 bytes superiores el número de menú seleccionado
  389.              y en los dos bytes inferiores, el número de la opción seleccionada
  390.              de dicho menú.
  391.              Para extraer ambos valores, emplearemos una funciones de la Toolbox,
  392.              HiWord y LoWord que nos devolverán los valores que nos interesan */
  393.              
  394.         Que_Menu = HiWord(algoSeleccionado);     /* 2 bytes superiores */
  395.         Que_Opcion = LoWord(algoSeleccionado);/* 2 bytes inferiores */
  396.         
  397.         switch(Que_Menu)
  398.         {
  399.             
  400.             case kArchivoMenuID:                                /* Menú Archivo (el único de momento)    */
  401.                 switch(Que_Opcion)
  402.                 {
  403.                     case kSalirItem:                                /* Opción 'Salir' (nº 1)                             */
  404.                         gAcabarProg = true;                        /* IMPORTANTE: Cambiamos el valor de
  405.                                                                                          la variable global que nos indica
  406.                                                                                          que debemos finalizar el programa     */
  407.                     break;                                                
  408.                         
  409.                 } /* Fin de switch(Que_Opcion) */
  410.                 
  411.             break;
  412.         } /* Fin de switch(Que_Menu) */
  413.         
  414.         HiliteMenu(0);
  415.         
  416.     } /* Fin de if(algoSeleccionado != 0L) */
  417.     
  418. } /* Fin de función MF_MenuBar() */
  419.  
  420.  
  421.  
  422. /****************************************************************    */
  423. /* MF_InitToolbox                                                                                                 */
  424. /****************************************************************    */
  425. /*
  426.     Inicializa la Toolbox Macintosh. El orden de llamada a las diversas
  427.     rutinas es significativo! No lo cambie.
  428.  
  429.     Recibe:     nada
  430.     Cambia:      nada en la aplicación
  431.     Salida:      nada
  432. */
  433. void MF_InitToolbox (void)
  434. {
  435.     InitGraf(&qd.thePort);
  436.     InitFonts();
  437.     FlushEvents(everyEvent,0);
  438.     InitWindows();
  439.     InitMenus();
  440.     TEInit();
  441.     InitDialogs(0L);
  442.     InitCursor(); /* La llamada a InitCursor() */
  443.                                 /* ajusta el cursor a la flecha estándar */ 
  444.                                 /* y lo hace visible */
  445.                                 
  446. } /* Fin de MF_InitToolbox() */
  447.  
  448.  
  449.  
  450. /****************************************************************    */
  451. /* MF_SetupMenus                                                                                                    */
  452. /****************************************************************    */
  453. /*
  454. Inicializa y muestra los menús del programa. En esta versión, es de destacar
  455. que NO implementamos el acceso al menú Apple (el de la manzanita...)
  456. En posteriores ejemplos se mostrará como instalarlo y acceder a él.
  457.  
  458.     Requiere: Recurso de tipo MENU en el fichero CdeCerca_3.µ.rsrc
  459.                         En concreto el recurso MENU nº 129 (kArchivoMenuID=129)
  460.     Recibe:     nada
  461.     Cambia:      asigna valor a las globales e instala el menú en la barra de menús
  462.     Salida:   nada
  463. */
  464. void MF_SetupMenus(void)
  465. {
  466.     /* Primero, leer el recurso de tipo MENU que contiene la propia aplicación */
  467.     /* Para ello, usamos la función GetMenu() de la Toolbox, que sólo requiere */
  468.     /* como parámetro, el nº del recurso. Lo hemos declarado en una constante, */
  469.     /* kArchivoMenuID al principio del código */
  470.     gArchivoMenu = GetMenu( kArchivoMenuID );
  471.     
  472.     /* Con el menú en memoria, instalarlo y mostrarlo es coser y cantar... */
  473.     /* Sólo hay que ejecutar la función InsertMenu(), también de la Toolbox */
  474.     /* pasándole como parámetro el valor devuelto por GetMenu() */
  475.     InsertMenu(gArchivoMenu, 0); 
  476.     
  477.     DrawMenuBar();     /* y por último, actualizamos la barra de menús para que */
  478.                                     /* se reflejen los cambios que acabamos de hacer. */
  479.     
  480. } /* Fin de MF_SetupMenus() */
  481.  
  482.  
  483.     
  484. /****************************************************************    */
  485. /* MF_AbreMiVentana                                                       */
  486. /****************************************************************    */
  487. /*
  488.     Abre la ventana (la única) de nuestro programa.
  489.     
  490.     Recibe:     nada
  491.     Que hace: Crea una ventana...
  492.     Salida:      void (nada)
  493. */
  494. void MF_AbreMiVentana(void)
  495. {
  496.     /* 
  497.     Programando el Mac hay más de una forma de crear y mostrar una ventana.
  498.     
  499.     De momento vamos a emplear la función de la Toolbox llamada NewWindow()
  500.     pasándole una serie de parámetros que describen las características
  501.     de la ventana (tamaño, título, posición, etc...)
  502.     
  503.     El prototipo de NewWindow es:
  504.     
  505.     NewWindow(void *wStorage,
  506.                         const Rect *boundsRect,
  507.                         ConstStr255Param title, 
  508.                         Boolean visible,
  509.                         short theProc,
  510.                         WindowRef behind,
  511.                         Boolean goAwayFlag,
  512.                         long refCon)
  513.     
  514.     De momento sólo comentaremos el significado de 4 parámetros que nos
  515.     interesan especialmente:
  516.     
  517.     *boundsrect:    Una variable de tipo Rect (rectángulo) que describe la
  518.                                 posición y tamaño de la nueva ventana.
  519.     title:                Una cadena de caracteres que forma el título de la ventana.
  520.     visible:            Un valor de tipo booleano indicando la visibilidad de la ventana.
  521.                                 true = visible. False = invisible.
  522.     theProc:            Tipo de ventana que deseamos, Podemos emplear una de las siguientes
  523.                                 constantes, definidas por Apple en el fichero Windows.h de
  524.                                 los Universal Headers:
  525.                                     documentProc
  526.                                     dBoxProc
  527.                                     plainDBox
  528.                                     altDBoxProc
  529.                                     noGrowDocProc
  530.                                     movableDBoxProc
  531.                                     zoomDocProc
  532.                                     zoomNoGrow
  533.                                     rDocProc
  534.     goAwayFlag:        Otro valor booleano que indica si la ventana debe tener cuadro
  535.                                 de cierre (true) o no (false).
  536.     
  537.     */
  538.     
  539.     /* Antes que nada, declarar una variable Rect y asignarle valores */
  540.     /* Rect es una estructura que contiene cuatro variables de tipo short */
  541.     /* llamadas top, left, bottom y right.
  542.     
  543.                     top 
  544.                         |
  545.                         v
  546.         left-->    +-----------------+
  547.                         |                                    |
  548.                         |                                    |
  549.                         |                                    |
  550.                         |                                    |
  551.                         +-----------------+ <-- right
  552.                                                             ^    
  553.                                                             |
  554.                                                         bottom
  555.     
  556.  
  557.     El rectángulo que definamos estará describiendo la posición y tamaño
  558.     de la ventana que deseamos crear.
  559.     */
  560.                         
  561.     Rect    miRectangulo = { 48,         /* top */
  562.                                                  8,         /* left */
  563.                                                  108,        /* bottom */
  564.                                                  250        /* right */
  565.                                                 };    
  566.     
  567.     gMiVentana = NewWindow(    nil,
  568.                                                     &miRectangulo,             /* Puntero al rectángulo */
  569.                                                     "\pC de Cerca - 3",        /* Título */
  570.                                                     true,                                /* visible */
  571.                                                     documentProc,                /* Cambie el tipo de ventana */
  572.                                                                                             /* para experimentar... */
  573.                                                     (WindowPtr)-1L,
  574.                                                     false,                            /* Sin cuadro de cierre */
  575.                                                     nil);
  576.   
  577.   if(gMiVentana == nil) 
  578.           ExitToShell();    /* Si la creación de la ventana falla, 
  579.                                               posiblemente sea debido a falta de memoria libre
  580.                                               Lo más aconsejable es salir de la aplicación */
  581.       
  582. } /* Fin de MF_AbreMiVentana() */
  583.  
  584.  
  585.  
  586. /****************************************************************/
  587. /* MF_EscribeTexto                                                                                         */ 
  588. /****************************************************************/
  589. /*
  590.     Dibuja en nuestra ventana un texto.
  591.         
  592.     Recibe:     Nada
  593.     Cambia:      Dibuja en la ventana un texto.
  594.     Salida:   Nada
  595. */
  596. void MF_EscribeTexto(void)
  597. {
  598.              MoveTo(30,30);
  599.              DrawString("\pMacFormat - C de Cerca nº 3");
  600.  
  601. }